package com.qianxun.framework.common.util;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Date;
import java.util.Properties;

/**
 * 邮箱工具
 *
 * @author: huwei
 * @date: 2019/10/14 10:24
 * @version: 1.0.0
 */
public class MailUtil {
    /**
     * 163smtp邮件服务地址
     */
    public static final String MAIL_SERVER_SMTP_163 = "smtp.163.com";
    /**
     * qq smtp邮件服务地址
     */
    public static final String MAIL_SERVER_SMTP_QQ = "smtp.qq.com";
    /**
     * 默认服务连接地址
     */
    public static final Integer MAIL_SERVER_PORT = 465;
    /**
     * 邮件协议
     */
    public static final String MAIL_SERVER_PROTOCOL = "smtp";
    /**
     * 邮件服务器地址
     */
    private String host;
    /**
     * 邮件服务器端口
     */
    private Integer port;
    /**
     * 邮件协议
     */
    private String protocol;
    /**
     * 邮件服务器登录用户
     */
    private String username;
    /**
     * 邮件服务器登录用户密码
     */
    private String password;

    /**
     * 静态工厂方法创建，减少发送方法参数太多，容易混淆的问题
     */
    private MailUtil(String host , Integer port , String protocol, String username , String password) {
        this.host = host;
        this.port = port;
        this.protocol = protocol;
        this.username = username;
        this.password = password;
    }

    public static MailUtil build163(String username , String password){
        return build(MAIL_SERVER_SMTP_163 ,MAIL_SERVER_PORT ,username,password);
    }

    public static MailUtil buildQQ(String username , String password){
        return build(MAIL_SERVER_SMTP_QQ ,MAIL_SERVER_PORT ,username,password);
    }

    public static MailUtil build(String host , Integer port , String username , String password){
        return build(host, port, MAIL_SERVER_PROTOCOL,username, password);
    }

    public static MailUtil build(String host , Integer port , String protocol, String username , String password ){
        return new MailUtil(host == null ? MAIL_SERVER_SMTP_163 : host
                , port == null ? MAIL_SERVER_PORT : port
                ,protocol == null ? MAIL_SERVER_PROTOCOL : protocol, username, password);
    }

    public void send(String to ,String subject ,String content) throws MessagingException {
        send(null ,to ,subject ,content);
    }

    public void send(String from ,String to ,String subject ,String content) throws MessagingException {
        if (to == null || to.trim().equals("")){
            throw new RuntimeException("邮件接收对象不能为空");
        }

        if(from == null || from.trim().equals("")){
            from = username;
        }

        Session session = Session.getInstance(properties(), mailAuthenticator());
        Transport.send(createMessage(session ,from ,to ,subject ,content));
    }

    private MimeMessage createMessage(Session session ,String from ,String to ,String subject ,String content) throws MessagingException {
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(from));
        message.addRecipient(Message.RecipientType.TO, new InternetAddress(to.trim()));
        message.setSubject(subject);
        message.setContent(content(content));
        message.setSentDate(new Date());
        message.saveChanges();
        return message;
    }

    private Multipart content(String content) throws MessagingException {
        MimeBodyPart mimeBodyPart = new MimeBodyPart();
        mimeBodyPart.setContent(content, "text/html;charset=utf-8");
        Multipart mp = new MimeMultipart();
        mp.addBodyPart(mimeBodyPart);
        return mp;
    }

    private Properties properties(){
        Properties props = new Properties();
        props.put("mail.transport.protocol" , protocol);
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.auth", "true");
        props.setProperty("mail.smtp.socketFactory.class" , "javax.net.ssl.SSLSocketFactory");
        props.setProperty("mail.smtp.socketFactory.fallback" , "false");
        props.setProperty("mail.smtp.port" , String.valueOf(port));
        props.setProperty("mail.smtp.socketFactory.port" , String.valueOf(port));
        return props;
    }

    private MailAuthenticator mailAuthenticator(){
        return new MailAuthenticator(username ,password);
    }

   /**
    * 邮箱验证对象
    * @author: huwei
    * @date:   2019/10/14 10:30
    * @version:  1.0.0
   */
    private class MailAuthenticator extends Authenticator {
        /**
         * POP3/SMTP服务  IMAP/SMTP服务的用户名
         */
        private String username;
        /**
         * POP3/SMTP服务  IMAP/SMTP服务的授权登录码
         */
        private String password;
        public MailAuthenticator(String username ,String password) {
            this.username = username;
            this.password = password;
        }
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
        }
    }
}
